﻿namespace AMS.Services.Impl;

public class MaintenanceRecordService : IMaintenanceRecordService
{
    private readonly DbContext _context;

    public MaintenanceRecordService(DbContext context)
    {
        _context = context;
    }

    public async Task<ListResult<MaintenanceRecord.QueryModel>> GetListAsync(CancellationToken cancellationToken)
    {
        var result = new ListResult<MaintenanceRecord.QueryModel>();

        try
        {
            var maintenanceRecords = await _context.Set<MaintenanceRecord>()
                .AsNoTracking()
                .ToListAsync(cancellationToken);

            result.Data = maintenanceRecords.Select(x => GetQueryModel(x));

            result.Status = OperationalResult.SUCCESS;
        }
        catch (Exception error)
        {
            result.Status = OperationalResult.ERROR;

            result.Message = error.ToString();
        }

        return result;
    }

    public async Task<PageResult<MaintenanceRecord.QueryModel>> GetPageAsync(PageParameter input, CancellationToken cancellationToken)
    {
        var result = new PageResult<MaintenanceRecord.QueryModel>();

        try
        {
            var maintenanceRecords = await _context.Set<MaintenanceRecord>()
                .Skip((input.PageNum - 1) * input.PageSize)
                .Take(input.PageSize)
                .AsNoTracking()
                .ToListAsync(cancellationToken);

            result.Data = maintenanceRecords.Select(x => GetQueryModel(x));

            result.PageNum = input.PageNum;

            result.PageSize = input.PageSize;

            result.Total = _context.Set<MaintenanceRecord>().Count();

            result.Status = OperationalResult.SUCCESS;
        }
        catch (Exception error)
        {
            result.Status = OperationalResult.ERROR;

            result.Message = error.ToString();
        }

        return result;
    }

    public async Task<OperationalResult> CreateAsync(MaintenanceRecord.CreateModel maintenanceRecord, CancellationToken cancellationToken)
    {
        var result = new OperationalResult();

        try
        {
            var entity = new MaintenanceRecord
            {
                Description = maintenanceRecord.Description,
                Overhauler = maintenanceRecord.Overhauler,
                Phone = maintenanceRecord.Phone,
                RepairDate = maintenanceRecord.RepairDate,
            };

            await _context.Set<MaintenanceRecord>().AddAsync(entity, cancellationToken);

            var affectedRows = await _context.SaveChangesAsync(cancellationToken);

            result.Status = affectedRows > 0 ? OperationalResult.SUCCESS : OperationalResult.FAILURE;

            result.Message = $"{affectedRows} rows affected.";
        }
        catch (Exception error)
        {
            result.Status = OperationalResult.ERROR;

            result.Message = error.ToString();
        }

        return result;
    }

    public async Task<OperationalResult> UpdateAsync(int id, MaintenanceRecord.UpdateModel maintenanceRecord, CancellationToken cancellationToken)
    {
        var result = new OperationalResult();

        try
        {
            var entity = await _context.Set<MaintenanceRecord>()
                .Where(m => m.Id.Equals(id))
                .FirstOrDefaultAsync(cancellationToken);

            if (entity is null)
            {
                result.Status = OperationalResult.FAILURE;

                result.Message = "0 rows affected.";

                return result;
            }

            entity.Description = maintenanceRecord.Description;
            entity.Overhauler = maintenanceRecord.Overhauler;
            entity.Phone = maintenanceRecord.Phone;
            entity.RepairDate = maintenanceRecord.RepairDate;

            _context.Set<MaintenanceRecord>().Update(entity);

            var affectedRows = await _context.SaveChangesAsync(cancellationToken);

            result.Status = affectedRows > 0 ? OperationalResult.SUCCESS : OperationalResult.FAILURE;

            result.Message = $"{affectedRows} rows affected.";
        }
        catch (Exception error)
        {
            var exists = await _context.Set<MaintenanceRecord>().AnyAsync(m => m.Id.Equals(id), cancellationToken);

            if (!exists)
            {
                result.Status = OperationalResult.FAILURE;

                result.Message = "0 rows affected.";
            }
            else
            {
                result.Status = OperationalResult.ERROR;

                result.Message = error.ToString();
            }
        }

        return result;
    }

    public static MaintenanceRecord.QueryModel GetQueryModel(MaintenanceRecord maintenanceRecord)
    {
        return new MaintenanceRecord.QueryModel
        {
            Id = maintenanceRecord.Id,
            CreatedDate = maintenanceRecord.CreatedDate,
            LastModifiedDate = maintenanceRecord.LastModifiedDate,
            Description = maintenanceRecord.Description,
            Overhauler = maintenanceRecord.Overhauler,
            Phone = maintenanceRecord.Phone,
            RepairDate = maintenanceRecord.RepairDate,
        };
    }
}